import { NGXLogger } from 'ngx-logger';
import { ParticipantPlayEvent } from './../../services/event.service';
import { TrackType } from './../../entity/ORTC';
import { Component, OnInit, OnChanges, SimpleChanges, Input, ElementRef, ViewChild, Renderer2 } from '@angular/core';

import { VideoContainer, VideoSize } from '../../entity/ORTC';
import { User, UserType, OPosition, Participant, OSize, Participants } from '../../entity/TT';
import { Utils } from 'src/app/common/Common';
import { EventService, EventSource, EventMessage, ParticipantSelectEvent, ParticipantMoveEvent, ParticipantSizeEvent, ParticipantGoHomeEvent } from '../../services/event.service';
import { CdkDrag, CdkDragStart, CdkDragEnd, CdkDragMove } from '@angular/cdk/drag-drop';


@Component({
  selector: 'app-video',
  templateUrl: './video.component.html',
  styleUrls: ['./video.component.scss']
})
export class VideoComponent implements OnInit, OnChanges {

  @Input()
  videoContainer: VideoContainer;


  private video: ElementRef;

  moveEvent: CdkDragMove<any>;
  cdkDrag: CdkDrag;
  isDraging = false;
  isResizing = false;

  mWidth: number;
  mHeight: number;

  midWidth: number = 170;
  midHeight: number;
  rWidth: number;
  rHeight: number;

  videoDom: any;
  audioDom: any;

  constructor(
    private log: NGXLogger,
    private el: ElementRef,
    private renderer: Renderer2,
    private eventService: EventService) {

      this.eventService.subscribeEvent((evt: EventMessage) => {
        switch (evt.source) {
          case EventSource.PARTICIPANT_GO_HOMEED:
            const pgme: ParticipantGoHomeEvent = evt.data;
            this.goHome(pgme);
            break;
          case EventSource.PARTICIPANT_MOVED:
            const pme: ParticipantMoveEvent = evt.data;
            this.move(pme);
            break;
          case EventSource.PARTICIPANT_SELECTED:
            const pse: ParticipantSelectEvent = evt.data;
            this.select(pse);
            break;
          case EventSource.PARTICIPANT_SIZE_CHANGED:
            const psc: ParticipantSizeEvent = evt.data;
            this.setSize(psc);
            break;
        }
      });

    }

    @ViewChild('videoBox', {static: false})
    set videoBox(ele: ElementRef) {
      setTimeout(() => {
        this.video = ele;
        if(this.video){
          const ref = ele['_el'];
          if (!ref) {
            return;
          }
          this.videoDom = ref.nativeElement.querySelector("video");
          this.audioDom = ref.nativeElement.querySelector("audio");
          // this.log.debug('videoContainer video', this.videoDom, 'audio', this.audioDom)


          // this.videoDom.addEventListener('play',   (e) => {
          //   this.log.debug('videoDom play...', e);
          // })

          // this.audioDom.addEventListener('play',  (e) => {
          //   this.log.debug('audioDom play...', e);
          // })
        }
      }, 20);
    }


  ngOnInit() {



  }

  ngOnChanges(changes: SimpleChanges) {

  }

  onVideoPlay(participantId: string) {
    this.log.debug('onVideoPlay', participantId);
    // const ppe: ParticipantPlayEvent = {
    //   participantId,
    //   trackType: TrackType.video
    // };
    // this.eventService.sendEvent(EventSource.TRACK_PLAYED,  ppe);
  }

  onAudioPlay(participantId: string) {
    this.log.debug('onAudioPlay', participantId);
    // const ppe: ParticipantPlayEvent = {
    //   participantId,
    //   trackType: TrackType.audio
    // };
    // this.eventService.sendEvent(EventSource.TRACK_PLAYED,  ppe);
  }


  onVideoError(participantId: string) {
    this.log.error('onVideoError', participantId);
  }

  onAudioError(participantId: string) {
    this.log.error('onAudioError', participantId);
  }

  move(pme: ParticipantMoveEvent) {
    if ( this.isMine(pme) ) {

      this.log.debug('move', pme);

      if (this.cdkDrag) {
        this.cdkDrag._dragRef.setFreeDragPosition({x: pme.position.x, y: pme.position.y});
      } else {

        const ve = this.video;
        this.log.debug('ve', typeof ve, ve);
        const re = ve['_el'].nativeElement;

        if (re) {
          this.renderer.setStyle(re, 'transform',
          `translate3d(${pme.position.x}px, ${pme.position.y}px, 0px)`);
        }
      }

    }
  }


  onSelect(active:boolean, send: boolean= true) {
    if (this.isDraging || this.isResizing) {
      return;
    }

    this.videoContainer.active = active;

    if (send) {
      const pse: ParticipantSelectEvent = {
        participantIds: [this.videoContainer.participantId],
        select: this.videoContainer.active
      };

      this.eventService.sendEvent(EventSource.PARTICIPANT_SELECT, pse);
    }
  }

  select(pse: ParticipantSelectEvent) {
    if (this.hasMine(pse)) {
      this.onSelect( pse.select, false);
    }
  }

  isActived(): boolean {
    return this.videoContainer.active;
  }

  isMine(p: Participant) {
    return this.videoContainer && this.videoContainer.participantId === p.participantId;
  }

  hasMine(p: Participants){
    return 0 <= p.participantIds.findIndex(e => {
      return e === this.videoContainer.participantId;
    })
  }

  isSmall() {
    if(this.video){
      const el = this.video['_el'];
      if (!el || !el.nativeElement)
        return true;

      const w = (el.nativeElement.clientWidth);
      return w < (this.midWidth - 50);
    }
  }

  getDurationFmt() {
    let fmt = '';
    if (this.videoContainer.beginTime) {
      setTimeout(() => {
        fmt = Utils.MillsToMMSS(Utils.nowTime() - this.videoContainer.beginTime);
      }, 400);
    }

    return fmt;
  }

  dragStarted(event: CdkDragStart) {
    this.log.debug('dragStarted', event);
    this.cdkDrag = event.source;

    if (!this.isActived()) {
      this.cdkDrag.disabled = true;
    }

    this.isDraging = true;
  }

  dragEnded(event: CdkDragEnd) {
    this.log.debug('dragEnded', event);

    const id = this.videoContainer.participantId;
    const pox = event.source.getFreeDragPosition();

    const data: ParticipantMoveEvent = {
      participantId: id,
      position: { x: pox.x, y: pox.y }
    };

    this.eventService.sendEvent(EventSource.PARTICIPANT_MOVE, data);

    setTimeout(() => {
      this.isDraging = false;
    }, 400);

  }

  dragMoved(event: CdkDragMove) {

  }

  resizeStart(event) {
    if (!this.videoContainer.active) {
      return false;
    }

    this.isResizing = true;

    if (this.cdkDrag) {
      this.cdkDrag.disabled = true;
    }
  }

  resizeEnd(event) {

    setTimeout(() => {
      this.isResizing = false;
      if (this.cdkDrag) {
        this.cdkDrag.disabled = false;
      }
    }, 400);
  }

  resizing(event) {

    this.rWidth = event.size.width;
    this.rHeight = event.size.height;

    const data: ParticipantSizeEvent = {
        participantId: this.videoContainer.participantId,
        size: { width: this.rWidth , height: this.rHeight }
      };

    this.eventService.sendEvent(EventSource.PARTICIPANT_SIZE, data);

  }

  resizeInit(event) {

  }

  goHome(pgme: ParticipantGoHomeEvent ) {

    if (this.isMine(pgme)) {
      const pme: ParticipantMoveEvent = {participantId: pgme.participantId, position: {x: 0, y: 0} };
      this.move(pme);
      this.resetSize();
    }
  }

  resetSize() {

    if (this.video) {
      const el = this.video['_el'];
      this.renderer.setStyle(el.nativeElement, 'width',  '100%');
      this.renderer.setStyle(el.nativeElement, 'height', '100%');
    }
  }

  setSize(psc: ParticipantSizeEvent) {
    if (this.isMine(psc)) {
      this.rWidth = psc.size.width;
      this.rHeight = psc.size.height;
    }
  }

}
